/*
 * COPYRIGHT. ShenZhen JiMi Technology Co., Ltd. 2017.
 * ALL RIGHTS RESERVED.
 *
 * No part of this publication may be reproduced, stored in a retrieval system, or transmitted,
 * on any form or by any means, electronic, mechanical, photocopying, recording, 
 * or otherwise, without the prior written permission of ShenZhen JiMi Network Technology Co., Ltd.
 *
 * Amendment History:
 * 
 * Date                   By              Description
 * -------------------    -----------     -------------------------------------------
 * 2017年7月24日    li.shangzhi         Create the class
 * http://www.jimilab.com/
 */

package com.jimi.api.instruct.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import net.sf.oval.constraint.Length;
import net.sf.oval.constraint.NotBlank;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.jimi.api.instruct.InstructionApi;
import com.jimi.api.instruct.vo.CommandLogsVo;
import com.jimi.api.instruct.vo.InstructionDetailsVo;
import com.jimi.api.instruct.vo.InstructionParamJson;
import com.jimi.app.api.IApiAppInfoApi;
import com.jimi.app.dto.output.ApiAppInfoOutputDto;
import com.jimi.dto.base.ApiResult;
import com.jimi.exception.ErrorCode;
import com.jimi.framework.base.BaseController;
import com.jimi.framework.bean.BeanUtil;
import com.jimi.framework.interceptor.loginsecurity.LoginSecurity;
import com.jimi.framework.utils.DESEncrypt;
import com.jimi.framework.utils.ResultModel;
import com.jimi.utils.MessageSourceUtil;
import com.jimi.web.api.IDevicesApiService;
import com.jimi.web.api.IInstructionApiService;
import com.jimi.web.dto.input.SendInstructionInputDto;
import com.jimi.web.dto.output.CommandLogsOutputDto;
import com.jimi.web.dto.output.DeviceInfoOutputDto;
import com.jimi.web.dto.output.InstructionDetailsOutputDto;

/**
 * @FileName InstructionController.java
 * @Description:
 *
 * @Date 2017年7月24日 下午4:17:11
 * @author li.shangzhi
 * @version 1.0
 */
@RestController
@RequestMapping(value = "/instructions")
public class InstructionController extends BaseController implements InstructionApi {

	@Autowired
	private IDevicesApiService devicesApiService;
	
	@Autowired
	private IInstructionApiService instructionApiService;
	
	@Autowired
	private IApiAppInfoApi apiAppInfoApi;
	
	@ResponseBody
	@LoginSecurity
	@RequestMapping(value = "/getInstructionList", params = { "method=jimi.open.instruction.list" }, produces = { "application/json" }, method = {
			RequestMethod.GET, RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> getInstructionList(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.accessToken.invalid") @Length(min = 10, max = 32, message = "api.accessToken.invalid") @RequestParam(value = "access_token", required = true) String accessToken,
			@NotBlank(message = "api.imei.invalid") @RequestParam(value = "imei", required = true) String imei,
			HttpServletRequest request) {
		String decrypt = DESEncrypt.decrypt(appKey);
		String[] strs = decrypt.split(",");
		String projectCode = strs[0];
		String userId = strs[1];
		DeviceInfoOutputDto deviceInfoOutputDto = devicesApiService.checkDeviceRange(userId, imei);
		if(null == deviceInfoOutputDto) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.INVALID_DEVICE_ERROR), HttpStatus.OK);
		}
		List<InstructionDetailsOutputDto> instList = instructionApiService.getInstructionByMcType(deviceInfoOutputDto.getMcType());
		ResultModel resultModel = new ResultModel();
		resultModel.setResult(BeanUtil.convertBeanList(instList, InstructionDetailsVo.class));
		return new ResponseEntity<ResultModel>(resultModel, HttpStatus.OK);
	}

	@ResponseBody
	@LoginSecurity
	@RequestMapping(value = "/sendInstruction", params = { "method=jimi.open.instruction.send" }, produces = { "application/json" }, method = { RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> sendInstruction(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.accessToken.invalid") @Length(min = 10, max = 32, message = "api.accessToken.invalid") @RequestParam(value = "access_token", required = true) String accessToken,
			@NotBlank(message = "api.imei.invalid") @RequestParam(value = "imei", required = true) String imei,
			@RequestParam(value = "inst_param_json", required = true) String instParamJson,
			HttpServletRequest request) {
		InstructionParamJson instJson = JSONObject.parseObject(instParamJson, InstructionParamJson.class);
		if(null == instJson.getInstId() || null == instJson.getInstTemplate()) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.PARAM_ERROR), HttpStatus.OK);
		}
		
		String decrypt = DESEncrypt.decrypt(appKey);
		String[] strs = decrypt.split(",");
		String projectCode = strs[0];
		String userId = strs[1];
		DeviceInfoOutputDto deviceInfoOutputDto = devicesApiService.checkDeviceRange(userId, imei);
		if(null == deviceInfoOutputDto) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.INVALID_DEVICE_ERROR), HttpStatus.OK);
		}
		ApiAppInfoOutputDto appInfo = apiAppInfoApi.getByAppKey(appKey);
		SendInstructionInputDto inputDto = new SendInstructionInputDto();
		inputDto.setImei(imei);
		inputDto.setUserId(userId);
		inputDto.setAccount(appInfo.getAccount());
		inputDto.setInstId(instJson.getInstId());
		inputDto.setInstTemplate(instJson.getInstTemplate());
		inputDto.setMcType(deviceInfoOutputDto.getMcType());
		inputDto.setParams(instJson.getParams());
		inputDto.setCover(instJson.isCover());
		ApiResult apiResult = instructionApiService.sendInstruction(inputDto);
		int code = apiResult.getResultCode();
		ResultModel resultModel = new ResultModel();
		if(code == 0) {
			resultModel.setCode(code);
			resultModel.setMessage(MessageSourceUtil.getMessage("api.instruction.send.ok"));
		} else {
			resultModel.setCode(12005);// 发送指令失败
			resultModel.setMessage(MessageSourceUtil.getMessage("api.instruction.send.fail", String.valueOf(code)));
		}
		return new ResponseEntity<ResultModel>(resultModel, HttpStatus.OK);
	}

	@ResponseBody
	@LoginSecurity
	@RequestMapping(value = "/getInstructionResult", params = { "method=jimi.open.instruction.result" }, produces = { "application/json" }, method = {
			RequestMethod.GET, RequestMethod.POST })
	@Override
	public ResponseEntity<ResultModel> getInstructionResult(
//			@NotBlank(message = "api.method.invalid") @Length(min = 10, max = 20, message = "api.method.invalid") @RequestParam(value = "method", required = true) String method,
			@NotBlank(message = "api.appkey.invalid") @Length(min = 10, max = 32, message = "api.appkey.invalid") @RequestParam(value = "app_key", required = true) String appKey,
//			@NotBlank(message = "api.timestamp.invalid") @DateRange(format = "yyyy-MM-dd HH:mm:ss", message = "api.timestamp.invalid") @RequestParam(value = "timestamp", required = true) String timestamp,
//			@NotBlank(message = "api.format.invalid") @MemberOf(value = { "json", "xml" }, message = "api.format.invalid") @RequestParam(value = "format", required = true) String format,
//			@NotBlank(message = "api.version.invalid") @MemberOf(value = { "1.0" }, message = "api.version.invalid") @RequestParam(value = "v", required = true) String v,
//			@NotBlank(message = "api.signmethod.invalid") @MemberOf(value = { "md5" }, message = "api.signmethod.invalid") @RequestParam(value = "sign_method", required = true) String signMethod,
//			@NotBlank(message = "api.sign.invalid") @Length(min = 10, max = 32, message = "api.sign.invalid") @RequestParam(value = "sign", required = true) String sign,
			@NotBlank(message = "api.accessToken.invalid") @Length(min = 10, max = 32, message = "api.accessToken.invalid") @RequestParam(value = "access_token", required = true) String accessToken,
			@NotBlank(message = "api.imei.invalid") @RequestParam(value = "imei", required = true) String imei,
			HttpServletRequest request) {
		String decrypt = DESEncrypt.decrypt(appKey);
		String[] strs = decrypt.split(",");
		String projectCode = strs[0];
		String userId = strs[1];
		DeviceInfoOutputDto deviceInfoOutputDto = devicesApiService.checkDeviceRange(userId, imei);
		if (null == deviceInfoOutputDto) {
			return new ResponseEntity<ResultModel>(new ResultModel(ErrorCode.INVALID_DEVICE_ERROR), HttpStatus.OK);
		}
		List<CommandLogsOutputDto> logsList = instructionApiService.getCommandLogsByImei(imei);
		ResultModel resultModel = new ResultModel();
		resultModel.setResult(BeanUtil.convertBeanList(logsList, CommandLogsVo.class));
		return new ResponseEntity<ResultModel>(resultModel, HttpStatus.OK);
	}

}
